﻿using Basic.FlowApplication.AuditLocalEvent;
using Basic.FlowApplication.Interface;
using Basic.FlowApplication.Model;
using Basic.FlowApplication.Model.AuditLog;
using Basic.FlowExtendService;
using Basic.FlowModel.AuditLog;
using Basic.FlowRemoteModel;
using Basic.FlowRemoteModel.Application.Model;
using WeDonekRpc.Client.Interface;
using WeDonekRpc.Client.Tran;
using WeDonekRpc.Helper;

namespace Basic.FlowApplication.Extend
{
    internal class SubmitAuditService : ISubmitAuditService
    {
        private readonly IAuditLogService _AuditLog;
        private readonly IFlowNodeService _Flow;
        private readonly IFileService _File;
        private readonly IIocService _Ioc;
        public SubmitAuditService ( IAuditLogService auditLog,
            IIocService ioc,
            IFileService file,
            IFlowNodeService flow )
        {
            this._File = file;
            this._Ioc = ioc;
            this._Flow = flow;
            this._AuditLog = auditLog;
        }

        public FlowAuditItemStatus Submit ( long logId, AuditRes result )
        {
            FlowAuditLogState log = this._AuditLog.GetLogState(logId);
            FlowAuditLogStatus oldStatus = log.Status;
            FlowAuditStatus oldAuditStatus = log.AuditStatus;
            AuditFlowBody flow = this._Flow.Get(log.FlowId);
            string key = "Audit_" + (int)result.AuditResult;
            if ( result.AuditResult == FlowAuditResult.审核通过 && result.Restore != null )
            {
                key = "Audit_99";
            }
            IItemAuditEvent audit = this._Ioc.Resolve<IItemAuditEvent>(key);
            AfootAuditLogItem item = audit.ItemAudit(flow, log, result);
            log.SyncNodeState();
            log.RefreshNodeState(flow, item);
            if ( item.Status == FlowAuditItemStatus.审核通过 ||
                item.Status == FlowAuditItemStatus.已取消 ||
                item.Status == FlowAuditItemStatus.审核未通过 ||
                item.Status == FlowAuditItemStatus.终审通过 )
            {
                log.CheckLogState(flow, item);
                if ( log.AuditStatus == FlowAuditStatus.审核未通过 )
                {
                    log.ToVoidRunItem(flow, flow.BeginNode, item.Id);
                }
            }
            if ( log.AuditStatus == FlowAuditStatus.待提交 )
            {
                log.AuditStatus = FlowAuditStatus.审核进行中;
            }
            SaveAuditBody body = log.GetAuditBody(flow);
            AuditLog res;
            if ( result.FileId.IsNull() && result.SignFileId.HasValue == false )
            {
                res = this._AuditLog.SaveResult(body);
            }
            else
            {
                long[] fileId = result.SignFileId.HasValue ? result.FileId.Add(result.SignFileId.Value) : result.FileId;
                using ( IRpcTransaction tran = new RpcTransaction("SugarDBTran") )
                {
                    res = this._AuditLog.SaveResult(body);
                    this._File.Save(fileId, result.ItemId);
                    tran.Complate();
                }
            }
            new FlowAuditEvent
            {
                OldLogStatus = oldStatus,
                OldAuditStatus = oldAuditStatus,
                Flow = flow,
                ItemId = result.ItemId,
                NodeState = body.NodeState,
                Item = item,
                Log = res
            }.AsyncSend();
            return item.AuditState;
        }
    }
}
